package com.travel.service.impl.User;

import com.travel.exception.BadRequestException;
import com.travel.exception.ResourceNotFoundException;
import com.travel.mapper.user.UserMapper;
import com.travel.model.dto.auth.PasswordChangeRequest;
import com.travel.model.dto.user.UserDTO;
import com.travel.model.dto.user.UserProfileUpdateDTO;
import com.travel.model.entity.auth.User;
import com.travel.service.Service.UserService;
import com.travel.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    
    private final UserMapper userMapper;  
    private final PasswordEncoder passwordEncoder;
    
    @Override
    public User getCurrentUser() {
        Long userId = SecurityUtils.getCurrentUserId();
        return userMapper.findById(userId)
            .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
    }

    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username)
            .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
    }

    @Override
    @Transactional
    public int registerUser(UserDTO userDTO) {
        if (existsByUsername(userDTO.getUsername())) {
            throw new BadRequestException("用户名已存在");
        }
        if (existsByEmail(userDTO.getEmail())) {
            throw new BadRequestException("邮箱已被使用");
        }

        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        user.setCreatedTime(LocalDateTime.now());
        user.setUpdatedTime(LocalDateTime.now());
        user.setStatus(1);
        
        return userMapper.insert(user);
    }

    @Override
    public boolean existsByUsername(String username) {
        return userMapper.existsByUsername(username);
    }

    @Override
    public boolean existsByEmail(String email) {
        return userMapper.existsByEmail(email);
    }

    @Override
    @Transactional
    public User updateProfile(UserDTO userDTO) {
        User currentUser = getCurrentUser();
        BeanUtils.copyProperties(userDTO, currentUser, "password", "username", "status");
        currentUser.setUpdatedTime(LocalDateTime.now());
        userMapper.update(currentUser);
        return currentUser;
    }

    @Override
    @Transactional
    public void changePassword(PasswordChangeRequest request) {
        User currentUser = getCurrentUser();
        if (!passwordEncoder.matches(request.getOldPassword(), currentUser.getPassword())) {
            throw new BadRequestException("原密码不正确");
        }
        currentUser.setPassword(passwordEncoder.encode(request.getNewPassword()));
        currentUser.setUpdatedTime(LocalDateTime.now());
        userMapper.update(currentUser);
    }

    @Override
    public Page<User> getAllUsers(Pageable pageable) {
        List<User> users = userMapper.findAll(pageable);
        long total = userMapper.count();
        return new PageImpl<>(users, pageable, total);
    }

    @Override
    @Transactional
    public void updateUserStatus(Long id, Integer status) {
        User user = getUserById(id);
        user.setStatus(status);
        user.setUpdatedTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    public User getUserById(Long id) {
        return userMapper.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
    }

    @Override
    @Transactional
    public void updateProfile(Long id, UserDTO userDTO) {
        User user = getUserById(id);
        BeanUtils.copyProperties(userDTO, user, "password", "username", "status");
        user.setUpdatedTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    @Transactional
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        User user = getUserById(id);
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new BadRequestException("原密码不正确");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdatedTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    @Transactional
    public User updateUserProfile(UserProfileUpdateDTO updateDTO) {
        User currentUser = getCurrentUser();
        
        // 只更新非null的字段
        if (updateDTO.getNickname() != null) {
            currentUser.setNickname(updateDTO.getNickname());
        }
        if (updateDTO.getEmail() != null) {
            // 检查邮箱是否被其他用户使用
            if (!updateDTO.getEmail().equals(currentUser.getEmail()) 
                && existsByEmail(updateDTO.getEmail())) {
                throw new BadRequestException("该邮箱已被使用");
            }
            currentUser.setEmail(updateDTO.getEmail());
        }
        if (updateDTO.getAvatar() != null) {
            currentUser.setAvatar(updateDTO.getAvatar());
        }
        if (updateDTO.getPhone() != null) {
            currentUser.setPhone(updateDTO.getPhone());
        }
        
        currentUser.setUpdatedTime(LocalDateTime.now());
        userMapper.update(currentUser);
        
        return currentUser;
    }
} 